package com.dure.hotmemory.scenes.tzxl;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.EmbossMaskFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.os.Build;

import com.dure.commonlib.util.PreferencesUtils;
import com.dure.hotmemory.R;
import com.dure.hotmemory.bean.Cell;
import com.dure.hotmemory.controllers.Controller;
import com.dure.hotmemory.drawview.BaseSurfaceView;
import com.dure.hotmemory.scenes.BaseScene;

import java.util.ArrayList;

/**
 * Created by leix on 8/16/16.
 */
public class PathFindView extends BaseScene {

    private Paint paint;
    private int lineSize = 5;
    private float circleRaidus;
    private ArrayList<Cell> pointList = new ArrayList<>();
    private int pointNumber = 3;
    float moveDistanceX, moveDistanceY;
    private boolean showLine;
    private int lineIndex;

    private int stepIndex;
    private boolean canChoise;
    private boolean showNext = true;
    private boolean datePrepared;
    private long startTime, restartWaitTime;
    private RectF leftBtnRectF, rightBtnRectF;
    private Bitmap heartBitmap;
    private int heartCount = 3;
    private String finishInfo;
    private boolean roundFinish, gameOver, restart, startDraw;
    private Cell wrongCell;
    float topStateHeight;
    long showNextWaitTime;
    Controller controller;
    boolean newRecordGet;
    private String alias;
    private EmbossMaskFilter emboss;
    int[] colors = {Color.WHITE, Color.parseColor("#00BDFF")};

    public PathFindView(BaseSurfaceView baseSurfaceView) {
        super(baseSurfaceView);
        controller = new Controller(this);
        init();
    }


    public void init() {
        paint = new Paint();
        paint.setColor(Color.WHITE);
        paint.setAntiAlias(true);
        paint.setStrokeWidth(lineSize);
        paint.setStyle(Paint.Style.FILL);

        circleRaidus = baseSurfaceView.getWidth() / 15;

        heartBitmap = BitmapFactory.decodeResource(activity.getResources(), R.mipmap.heart);
        topStateHeight = baseSurfaceView.getWidth() * 0.12f;
        alias = PreferencesUtils.getString(activity, "current_alias");

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
            float[] direction = new float[] { 1, 1, 1 };
            // 设置环境光亮度
            float light = 0.5f;
            // 选择要应用的反射等级
            float specular = 10;// 这个参数更改没有看出效果上面的变化
            // 向mask应用一定级别的模糊
            float blur = 3;// 这个参数可以控制立体侧面的宽度
            emboss = new EmbossMaskFilter(direction, light, specular, blur);
            paint.setMaskFilter(emboss);
        }


    }

    @Override
    public void handleData() {

        if (showNext) {
            showNext = false;
            canChoise = false;
            lineIndex = 0;

            getPathPoints();

            datePrepared = true;
            startTime = System.currentTimeMillis();
            startDraw = true;
        }

        if (System.currentTimeMillis() - startTime > 1000) {
            showLine = true;
        }

        if (showLine && lineIndex + 1 >= pointList.size()) {
            showLine = false;
            canChoise = true;
        }

        if (wrongCell != null && System.currentTimeMillis() - startTime > 1000) {

            wrongCell.selected = false;
            wrongCell.selectedColor = Color.WHITE;
            wrongCell = null;

            if (heartCount == 0) {
//                stepIndex = 0;
//                heartCount = 3;
//                pointNumber = 3;
                gameOver = true;
                finishInfo = "挑战失败，请再接再厉！";

            }
        }


        if (roundFinish && System.currentTimeMillis() - showNextWaitTime > 1000) {// 成功
            roundFinish = false;
            stepIndex = 0;
            showNext = true;
            pointNumber += 1;
        }

        if (restart && System.currentTimeMillis() - restartWaitTime > 1000){
            restart = false;
            stepIndex = 0;
            heartCount = 3;
            pointNumber = 3;
            showNext = true;
        }

    }


    private void getPathPoints() {
        pointList.clear();
        int viewWith = baseSurfaceView.getWidth();
        int viewHeight = baseSurfaceView.getHeight();
        while (pointList.size() < pointNumber) {
            float x = (float) (Math.random() * (viewWith - 2 * circleRaidus)) + circleRaidus;
            float y = (float) (Math.random() * (viewHeight - 2 * circleRaidus - topStateHeight)) + circleRaidus + topStateHeight;

            RectF newRectF = new RectF();
            Path newPath = new Path();
            newPath.addCircle(x, y, circleRaidus, Path.Direction.CCW);
            newPath.computeBounds(newRectF, true);

            Cell cell = new Cell();
            cell.color = Color.WHITE;
            cell.rectF = newRectF;
            if (pointList.size() == 0) {
                cell.pointF = new PointF(x, y);
                pointList.add(cell);
            } else {
                boolean intersect = false;
                for (Cell oldCell : pointList) {
                    RectF rectF = new RectF();
                    Path path = new Path();
                    path.addCircle(oldCell.pointF.x, oldCell.pointF.y, circleRaidus, Path.Direction.CCW);
                    path.computeBounds(rectF, true);
                    if (rectF.intersect(newRectF)) {// 如果与之前的有相交, 则重新获取
                        intersect = true;
                        break;
                    }
                }

                if (!intersect) {
                    cell.pointF = new PointF(x, y);
                    pointList.add(cell);
                }
            }
        }
    }

    @Override
    public void handleDraw(Canvas canvas) {
        if (!datePrepared)
            return;


        if (gameOver) {
            drawFinishDialog(canvas);
        } else if (startDraw){
            drawHeart(canvas);
            drawScore(canvas);

            if (showLine) {
                drawPath(canvas);

                drawLines(canvas);
            }

            drawCircles(canvas);

        }
    }

    private void drawCircles(Canvas canvas) {
        for (int i = 0; i < pointList.size(); i++) {
            Cell cell = pointList.get(i);
            PointF centerPoint = cell.pointF;
            if (cell.selected) {
                paint.setColor(cell.selectedColor);
            } else
                paint.setColor(cell.color);
            canvas.drawCircle(centerPoint.x, centerPoint.y, circleRaidus, paint);
        }

    }

    private void drawPath(Canvas canvas) {
        PointF pointF1 = pointList.get(lineIndex).pointF;
        PointF pointF2 = pointList.get(lineIndex + 1).pointF;

        float distanceX = Math.abs(pointF2.x - pointF1.x);
        float distanceY = Math.abs(pointF2.y - pointF1.y);


        float stepX = (pointF2.x - pointF1.x) / 60;
        float stepY = (pointF2.y - pointF1.y) / distanceY * (distanceY / distanceX) * Math.abs(stepX);
        if (Math.abs(moveDistanceX) < distanceX) {
            moveDistanceX += stepX;
            moveDistanceY += stepY;
        } else {
            lineIndex++;
            moveDistanceX = 0;
            moveDistanceY = 0;
        }

        float endPointX = pointF1.x + moveDistanceX;
        float endPointY = pointF1.y + moveDistanceY;
        paint.setColor(Color.WHITE);
        canvas.drawLine(pointF1.x, pointF1.y, endPointX, endPointY, paint);


    }

    private void drawLines(Canvas canvas) {
        paint.setColor(Color.WHITE);
        if (lineIndex > 0) {
            for (int i = 0; i < lineIndex; i++) {
                PointF pointF1 = pointList.get(i).pointF;
                PointF pointF2 = pointList.get(i + 1).pointF;

                canvas.drawLine(pointF1.x, pointF1.y, pointF2.x, pointF2.y, paint);

            }
        }
    }

    private void drawHeart(Canvas canvas) {
        Rect srcRect = new Rect(0, 0, heartBitmap.getWidth(), heartBitmap.getHeight());

        float dstHeartSize = topStateHeight * 0.8f;
        float leftPadding = topStateHeight * 0.2f;
        float topPadding = leftPadding;
        for (int i = 0; i < heartCount; i++) {
            float dstLeft = leftPadding * (i + 1) + i * dstHeartSize;
            float dstTop = topPadding;
            float dstRight = dstLeft + dstHeartSize;
            float dstBottom = dstTop + dstHeartSize;
            RectF dstRect = new RectF(dstLeft, dstTop, dstRight, dstBottom);

            canvas.drawBitmap(heartBitmap, srcRect, dstRect, null);
        }
    }

    private void drawScore(Canvas canvas) {
        String scoreStr = String.format("%d/%d", stepIndex, pointList.size());
        String recordStr = String.format("Best:%d", PreferencesUtils.getInt(activity, alias + ":best", 0));

        float textSize = topStateHeight * 0.6f;
        paint.setTextSize(textSize);

        float scoreWidth = paint.measureText(scoreStr);
        float contentWidth = paint.measureText(recordStr);
        float rightPadding = topStateHeight * 0.2f;
        float topPadding = rightPadding;

        float contentLeft = canvas.getWidth() - rightPadding - contentWidth;
        float contentBottom = topPadding + textSize;

        paint.setColor(Color.WHITE);
        canvas.drawText(recordStr, contentLeft, contentBottom, paint);

        float scoreLeft = canvas.getWidth() / 2 - scoreWidth / 2;
        float scoreBottom = contentBottom;
        canvas.drawText(scoreStr, scoreLeft, scoreBottom, paint);
    }

    private void drawFinishDialog(Canvas canvas) {
        String infoStr = String.format(finishInfo, pointList.size());
        String exitStr = "退出";
        String continueStr = "重来";

        float dialogWidth = canvas.getWidth() * 0.8f;
        float dialogHeight = dialogWidth * 0.6f;
        float infoPartHeight = dialogHeight * 0.7f;
        float btnPartHeight = dialogHeight * 0.3f;

        float infoTextSize = dialogWidth * 0.8f / infoStr.length();

        // 绘制dialog frame
        float dialogLeft = canvas.getWidth() / 2 - dialogWidth / 2;
        float dialogTop = canvas.getHeight() / 2 - dialogHeight / 2;
        float dialogRight = canvas.getWidth() / 2 + dialogWidth / 2;
        float dialogBottom = canvas.getHeight() / 2 + dialogHeight / 2;
        RectF dialogRectF = new RectF(dialogLeft, dialogTop, dialogRight, dialogBottom);
        paint.setColor(Color.WHITE);
        float arc = dialogRectF.width() / 15;

        LinearGradient lg = new LinearGradient(dialogRectF.width() /2, 0, dialogRectF.width() /2, dialogRectF.height(), colors, null, Shader.TileMode.MIRROR);
        paint.setShader(lg);
        canvas.drawRoundRect(dialogRectF, arc, arc, paint);
        paint.setShader(null);

        // 绘制info
        paint.setTextSize(infoTextSize);
        float infoWidth = paint.measureText(infoStr);
        float infoLeft = canvas.getWidth() / 2 - infoWidth / 2;
        float infoBottom = dialogTop + infoPartHeight / 2 + infoTextSize / 2;
        paint.setColor(Color.RED);
        canvas.drawText(infoStr, infoLeft, infoBottom, paint);

        float btnWidth = dialogWidth * 0.3f;
        float btnHeight = btnWidth / 2.5f;
        float btnTextSize = btnHeight * 0.6f;

        // 绘制左边btn
        float leftBtnLeft = canvas.getWidth() / 2 - dialogWidth / 4 - btnWidth / 2;
        float leftBtnBottom = dialogBottom - btnPartHeight / 2 + btnHeight / 2;
        float leftBtnRight = leftBtnLeft + btnWidth;
        float leftBtnTop = leftBtnBottom - btnHeight;
        leftBtnRectF = new RectF(leftBtnLeft, leftBtnTop, leftBtnRight, leftBtnBottom);
        arc = leftBtnRectF.width() / 15;
        paint.setColor(Color.parseColor("#00BDFF"));
        canvas.drawRoundRect(leftBtnRectF, arc, arc, paint);

        paint.setTextSize(btnTextSize);
        float exitStrWidth = paint.measureText(exitStr);
        float exitLeft = leftBtnLeft + btnWidth / 2 - exitStrWidth / 2;
        float exitBottom = leftBtnBottom - btnHeight * 0.3f;
        paint.setColor(Color.WHITE);
        canvas.drawText(exitStr, exitLeft, exitBottom, paint);

        // 绘制右边btn
        float rightBtnLeft = canvas.getWidth() / 2 + dialogWidth / 4 - btnWidth / 2;
        float rightBtnBottom = leftBtnBottom;
        float rightBtnRight = rightBtnLeft + btnWidth;
        float rightBtnTop = leftBtnTop;
        rightBtnRectF = new RectF(rightBtnLeft, rightBtnTop, rightBtnRight, rightBtnBottom);
        arc = rightBtnRectF.width() / 15;
        paint.setColor(Color.parseColor("#00BDFF"));
        canvas.drawRoundRect(rightBtnRectF, arc, arc, paint);

        paint.setTextSize(btnTextSize);
        float continueStrWidth = paint.measureText(continueStr);
        float continueLeft = rightBtnLeft + btnWidth / 2 - continueStrWidth / 2;
        float continueBottom = rightBtnBottom - btnHeight * 0.3f;
        paint.setColor(Color.WHITE);
        canvas.drawText(continueStr, continueLeft, continueBottom, paint);
    }


    float downX, downY;

    @Override
    public void handleDown(PointF pointF) {
        downX = pointF.x;
        downY = pointF.y;
    }

    @Override
    public void handleUp(PointF pointF) {
        float upX = pointF.x;
        float upY = pointF.y;

        if (Math.abs(downX - upX) < 50
                && Math.abs(downY - upY) < 50) {// 视为点击
            isChooseRight(downX, downY);

        } else {// 视为拖动

        }
    }

    private void isChooseRight(float x, float y) {
        if (!canChoise) {
            return;
        }

        if (wrongCell != null)
            return;

        if (gameOver) {
            if (leftBtnRectF.contains(x, y)) {
                gameOver = false;
                activity.backToLastScene();
            } else if (rightBtnRectF.contains(x, y)) {
                gameOver = false;
//                showNext = true;

                restart = true;
                startDraw = false;
                restartWaitTime = System.currentTimeMillis();
            }


        } else {
            Cell currentSelectCell = pointList.get(stepIndex);

            if (!currentSelectCell.selected && currentSelectCell.rectF.contains(x, y)) {// 选择正确
                currentSelectCell.selected = true;
                currentSelectCell.isCorrect = true;
                currentSelectCell.selectedColor = Color.GREEN;
                stepIndex++;

                if (stepIndex == pointList.size()) {
                    showNextWaitTime = System.currentTimeMillis();

                    int oldBest = PreferencesUtils.getInt(activity, alias + ":best", 0);
                    if (oldBest < pointNumber) {
                        newRecordGet = true;
                        PreferencesUtils.putInt(activity, alias + ":best", pointNumber);
                    }

                    roundFinish = true;
                }

            } else {// 要么是没有点中circle, 要么是选错,从stepIndex开始排除已经选择了的circle
                for (int i = stepIndex + 1; i < pointList.size(); i++) {
                    Cell oldCell = pointList.get(i);

                    if (!oldCell.selected && oldCell.rectF.contains(x, y)) {
                        wrongCell = oldCell;
                        oldCell.selected = true;
                        oldCell.isCorrect = false;
                        oldCell.selectedColor = Color.RED;
                        heartCount--;
                        startTime = System.currentTimeMillis();
                        break;
                    }
                }

            }
        }


    }

    @Override
    public void handleBack() {
        if (PreferencesUtils.getBoolean(activity, "login_success")){
            if (newRecordGet) {
                int level = PreferencesUtils.getInt(activity, alias + ":best", 0);
                controller.uploadTrainingData(String.valueOf(level), alias);
            }
        }
    }
}
